class Archivo < ActiveRecord::Base
	validates_presence_of :codigo
	#validates_presence_of :tc
	validates_presence_of :fecha_arribo
	
	belongs_to :cliente
	belongs_to :moneda
	belongs_to :estado_presupuesto
	belongs_to :paquete
	has_many :actividades, :class_name => "ArchivoActividad", :dependent=>:destroy
	has_many :sps, :class_name => "ArchivoSp"	
	has_many :reservas, :dependent=>:destroy
	has_many :reserva_sps, :dependent=>:destroy, :order=>[:fecha]
	has_many :pasajeros, :dependent=>:destroy
	has_many :comprobantes_pago
	
	def self.anios
		sql = "select 
			distinct year(fecha_arribo) as ano
		from
			archivos"
		
		Archivo.find_by_sql(sql)
	end
	
	def fecha_termino
		max = nil
		for actividad in actividades
			max||=actividad.fecha
			max = actividad.fecha if actividad.fecha > max
		end
		max
	end
	
	def fecha_pago
		if fecha_termino.day >= 15
			Date.new(fecha_termino.year, fecha_termino.month, (fecha_termino.month==2 ? 28 : 30))
		else
			Date.new(fecha_termino.year, fecha_termino.month, 15)
		end
	end
	
	def reservas_nuevas
		@reservas_nuevas = []		
		reserva_sps_sin_reserva.each{|sp|
			r = obtener_reserva_de(@reservas_nuevas, sp)
			if r == nil
				r = generar_reserva(@reservas_nuevas, sp.servicio.proveedor_id)
			end
			r.agregar_sp(sp)
		}		
		@reservas_nuevas		
	end
	
	def reservas_confirmadas
		reservas.select { |reserva| reserva.confirmada? }
	end
	
	def reserva_sps_sin_reserva
		rpta=[]
		reserva_sps.each{|rsp|			
			if rsp.sin_reserva?
				rpta << rsp
			end			
		}
		rpta
	end		
	
	def to_s
		codigo
	end
	
	def nro_personas
		nro_paxs + nro_soportes
	end
	
	def presupuesto_generado?
		actividades.size > 0	
	end
	
	def generar_presupuesto
		# 0. Estado del presupuesto
			self.estado_presupuesto_id = 1 #Abierto
			self.presupuestado_costo = 0
			self.presupuestado_utilidad = 0
			self.presupuestado_precio = 0		  	
			self.adicionales_costo = 0
			self.adicionales_utilidad = 0
			self.adicionales_precio = 0		  	
		# 1. Generar Actividades
	  	actividades << paquete.actividades.map{|pa| 
	  		aa = ArchivoActividad.generar(pa, nro_personas, fecha_arribo, moneda)
	  		
	  		self.presupuestado_costo += aa.costo
				self.presupuestado_utilidad += aa.utilidad
				self.presupuestado_precio += aa.precio
				
				aa
  		}  		
	end
	
	def pasajeros_generados?
		pasajeros.size > 0	
	end
	
	def generar_pasajeros				
  	pasajeros << Array.new(nro_paxs.to_i) { |pp|    	
  		pp = Pasajero.new(:tipo_persona_id=>2)	  		
  	}
		pasajeros << Array.new(nro_soportes.to_i) { |pp|  			
  		pp = Pasajero.new(:tipo_persona_id=>3)	  		
  	}
	end
	
	def reservas_generadas?
		reservas.size > 0
	end
	
	def generar_reservas		
		# 1. Generar Reservas (Ordenes de Servicio)
		reserva_sps.each { |reserva_sp| 
			r = obtener_reserva_de(reservas, reserva_sp)
			if r == nil
				r = generar_reserva(reservas, reserva_sp.servicio.proveedor_id)
			end
			r.agregar_sp(reserva_sp)
		}
		# 2. Generar Programacion de Pagos
		reservas.each { |r| 
			r.programaciones_pago<< ProgramacionPago.new(
				:fecha_max=> fecha_pago, #fecha_termino, #  r.fecha_min, 
				:porcentaje => 100, 
				:moneda => r.moneda, 
				:monto => r.total)		
		}
	end
	
	def confidencial_generado?
		reserva_sps.size > 0
	end	
	
	def generar_confidencial
		# 1. Generar Confidencial
		actividades.each { |actividad| 
			actividad.servicios.each { |servicio| 
				servicio.reserva_sps << servicio.sps.map { |asp|  
					ReservaSp.new(
						:servicio_id => asp.servicio_id, 
						:moneda_id => asp.moneda_id, 
						:precio_publicado => asp.precio_publicado,	
						:precio_extranjero => asp.precio_extranjero, 
						:precio_nacional => asp.precio_nacional, 
						:utilidad_porcentaje => asp.utilidad_porcentaje, 
						:utilidad_ajustada => asp.utilidad_ajustada, 
						:fecha_calculo => asp.fecha_calculo, 
						:cantidad => asp.cantidad,
						:nro_paxs => asp.nro_paxs,
						:archivo_id => id,
						:fecha => servicio.fecha
					)
				} 
			} 
		}		
	end
	
	def archivo_servicios
		sql = "select 
			ss.id, 
			concat(ss.fecha, ' : ', aa.nombre,' > ',ss.nombre) as nombre
		from
			archivo_actividades aa inner join archivo_servicios ss
				on ss.archivo_actividad_id = aa.id
		where
			aa.archivo_id = #{id}"
		
		ArchivoServicio.find_by_sql(sql)			
	end
	
	def comprobantes_pago
		ComprobantePago.find_by_sql("select 
					cp.* 
				from 
					comprobantes_pago cp
					JOIN reservas r ON cp.reserva_id = r.id
				where 
					r.archivo_id = #{id}")
	end		
	
	#Reportes PDF
	def to_pdf(tipo=nil)
		pdf = PDF::Writer.new(:paper=>'A4')
		pdf.select_font "Times-Roman"		
		pdf.margins_cm(0.5)
				
		render_cabecera(pdf, tipo)		
		render_servicios(pdf, tipo)		
				
		pdf.render
	end
	
	def to_excel
		rpta = "
		<table border='1'>
			<tr>
				<th rowspan='2'>Fecha</th>
				<th colspan='3'>Documento</th>
				<th colspan='2'>Detalle</th>
				<th colspan='2'>Importe</th>
			</tr>
			<tr>
				<th>Clase</th>
				<th>Serie</th>
				<th>Numero</th>
				<th>Grupo</th>
				<th>Proveedor</th>
				<th>Soles</th>
				<th>Dolares</th>
			</tr>"
			for _reserva in resumen_ordenes_servicio
				rpta += "<tr>
					<td></td>
					<td>O.S.</td>
					<td></td>
					<td>#{_reserva.OS}</td>
					<td>#{codigo}</td>
					<td>#{_reserva.PROVEEDOR}</td>
					<td>#{_reserva.SOLES}</td>
					<td>#{_reserva.DOLARES}</td>
				</tr>"
			end
				rpta += "</table>"		
	end	
		
	private
	def render_cabecera(pdf, tipo)		
		pdf.add_text_wrap(pdf.absolute_left_margin, pdf.absolute_top_margin - 25, 150, "TRANS TREKPERU E.I.R.L.")
		if tipo == "confidencial"
			pdf.text "CONFIDENCIAL DE SERVICIOS", :font_size => 14, :justification=>:center
		elsif tipo == "resumen_os"
			pdf.text "RESUMEN DE ORDENES DE SERVICIO", :font_size => 14, :justification=>:center
		elsif tipo == "liquidacion"
			pdf.text "LIQUIDACION DE SERVICIO", :font_size => 14, :justification=>:center
		end
		pdf.text "ARCHIVO : #{codigo}", :font_size => 10 #, :justification=>:center
		pdf.text "ARRIBO : #{fecha_arribo}", :font_size => 10 #, :justification=>:center
		pdf.text "NRO PAXS : #{nro_personas}", :font_size => 10 #, :justification=>:center
		pdf.text "GUIA/TC : #{tc}", :font_size => 10 #, :justification=>:center
		pdf.text "CLIENTE : #{cliente}", :font_size => 10 #, :justification=>:center
		pdf.text	"-"*170
	end
	
	def detalle_confidencial
		ReservaSp.find_by_sql(["select
				rs.FECHA,
				s.nombre as SERVICIO,
				p.nombre as PROVEEDOR,
				rs.cantidad as C,
				m.simbolo as M,
				rs.precio_extranjero as PU,
				CASE
					WHEN rs.total_manual IS NULL THEN rs.precio_extranjero*rs.cantidad
					ELSE rs.total_manual
				END as TOTAL,
				rs.observacion as OBSERVACION
			from 
				reserva_sps rs inner join servicios s
					on rs.servicio_id = s.id
				inner join proveedores p
					on s.proveedor_id = p.id
				inner join monedas m
					on rs.moneda_id = m.id
			where
				rs.archivo_id = #{id}
			order by rs.fecha"])
	end
	
	def resumen_ordenes_servicio
		Reserva.find_by_sql(["select 				
				r.id AS OS,
				ts.nombre AS TIPO, 
				p.nombre AS PROVEEDOR, 
				m.simbolo AS MON, 
				SUM(CASE
					WHEN rs.moneda_id = 1 AND total_manual is NOT NULL THEN total_manual
					WHEN rs.moneda_id = 1 AND total_manual is NULL THEN cantidad*precio_extranjero
					ELSE 0.00
					END) AS SOLES,
				SUM(CASE
					WHEN rs.moneda_id = 2 AND total_manual is NOT NULL THEN total_manual
					WHEN rs.moneda_id = 2 AND total_manual is NULL THEN cantidad*precio_extranjero
					ELSE 0.00
					END) AS DOLARES
			from 
				reservas r
				INNER JOIN proveedores p ON r.proveedor_id = p.id
				INNER JOIN tipos_servicio ts ON p.tipo_servicio_id = ts.id
				INNER JOIN reservas_sp_reservas rsr ON r.id = rsr.reserva_id
				INNER JOIN reserva_sps rs ON rs.id = rsr.reserva_sp_id
				INNER JOIN monedas m ON rs.moneda_id = m.id
			where
				r.archivo_id = #{id}
				AND NOT EXISTS(
					select * 
					from seguimientos_reserva 
					where	estado_reserva_id = 5	AND reserva_id = r.id)	
			group by 
				r.archivo_id, r.id, ts.nombre, p.nombre, rs.moneda_id"])
	end
	
	def resumen_comprobantes
		ComprobantePago.find_by_sql(["select 
			cp.fecha AS FECHA, 
			cp.reserva_id as RESERVA,
			tc.simbolo AS TIPO, 	
			cp.nro_serie AS NRO_SERIE,
			cp.proveedor AS DETALLE, 
			CASE
				WHEN cp.moneda_id = 1 THEN cp.total
				ELSE 0.00
				END AS SOLES,
			CASE
				WHEN cp.moneda_id = 2 THEN cp.total
				ELSE 0.00
				END AS DOLARES,
			tcc.precio_venta as TC,
			CASE
			WHEN cp.moneda_id = 1 THEN ROUND(cp.total / tcc.precio_venta, 2)
				WHEN cp.moneda_id = 2 THEN cp.total
			END AS EQUIV
		from 
			comprobantes_pago cp
			JOIN tipos_comprobante tc ON cp.tipo_comprobante_id=tc.id			
			LEFT JOIN tipos_cambio tcc ON tcc.fecha = cp.fecha
		where
			cp.archivo_id = #{id}
		order by
			cp.fecha, cp.reserva_id"])
	end
	
	def render_servicios(pdf, tipo)
		tabla = PDF::SimpleTable.new
		tabla.heading_font_size = 10
		tabla.font_size = 9
		tabla.show_lines = :none
		tabla.shade_rows = :none
		tabla.position = :left
		tabla.orientation = :right
		tabla.width = 580
		if tipo == 'confidencial'
			tabla.column_order = ['FECHA', 'SERVICIO', 'PROVEEDOR', 'C', 'M', 'PU', 'TOTAL', 'OBSERVACION']		
			tabla.columns["FECHA"] = PDF::SimpleTable::Column.new("FECHA") { |col|			
				col.width = 55
			}
			tabla.columns["SERVICIO"] = PDF::SimpleTable::Column.new("SERVICIO") { |col|			
				col.width = 140
			}
			tabla.columns["PROVEEDOR"] = PDF::SimpleTable::Column.new("PROVEEDOR") { |col|			
				col.width = 140
			}
			tabla.columns["C"] = PDF::SimpleTable::Column.new("C") { |col|			
				col.width = 20
				col.justification = :right
			}
			tabla.columns["M"] = PDF::SimpleTable::Column.new("M") { |col|			
				col.width = 30
				col.justification = :right
			}
			tabla.columns["PU"] = PDF::SimpleTable::Column.new("PU") { |col|			
				col.width = 35
				col.justification = :right
			}
			tabla.columns["TOTAL"] = PDF::SimpleTable::Column.new("TOTAL") { |col|			
				col.width = 45
				col.justification = :right
			}
			tabla.columns["OBSERVACION"] = PDF::SimpleTable::Column.new("OBSERVACION") { |col|
			}
			tabla.data = detalle_confidencial
		elsif tipo=='resumen_os'
			tabla.column_order = ['OS', 'TIPO', 'PROVEEDOR', 'MON', 'SOLES', 'DOLARES']		
			tabla.columns["OS"] = PDF::SimpleTable::Column.new("OS") { |col|			
				col.width = 30
			}
			tabla.columns["TIPO"] = PDF::SimpleTable::Column.new("TIPO") { |col|			
				col.width = 100
			}
			tabla.columns["PROVEEDOR"] = PDF::SimpleTable::Column.new("PROVEEDOR") { |col|			
				col.width = 140
			}
			tabla.columns["MON"] = PDF::SimpleTable::Column.new("MON") { |col|			
				col.width = 40
				col.justification = :right
			}
			tabla.columns["SOLES"] = PDF::SimpleTable::Column.new("SOLES") { |col|			
				col.width = 60
				col.justification = :right
			}
			tabla.columns["DOLARES"] = PDF::SimpleTable::Column.new("DOLARES") { |col|			
				col.width = 60
				col.justification = :right
			}
			
			tabla.data = resumen_ordenes_servicio
		elsif tipo=='liquidacion'
			tabla.column_order = ['FECHA', 'RESERVA', 'TIPO', 'NRO_SERIE', 'DETALLE', 'SOLES', 'DOLARES', 'TC', 'EQUIV']		
			tabla.columns["FECHA"] = PDF::SimpleTable::Column.new("FECHA") { |col|			
				col.width = 60
			}
			tabla.columns["RESERVA"] = PDF::SimpleTable::Column.new("RESERVA") { |col|				
				col.width = 58
				col.justification = :center
			}
			tabla.columns["TIPO"] = PDF::SimpleTable::Column.new("TIPO") { |col|			
				col.width = 35
				col.justification = :center
			}
			tabla.columns["NRO_SERIE"] = PDF::SimpleTable::Column.new("NRO_SERIE") { |col|			
				col.width = 70
				col.justification = :center
			}
			tabla.columns["DETALLE"] = PDF::SimpleTable::Column.new("DETALLE") { |col|			
				col.width = 140				
			}
			tabla.columns["SOLES"] = PDF::SimpleTable::Column.new("SOLES") { |col|			
				col.width = 50
				col.justification = :right
			}
			tabla.columns["DOLARES"] = PDF::SimpleTable::Column.new("DOLARES") { |col|			
				col.width = 60
				col.justification = :right
			}
			tabla.columns["TC"] = PDF::SimpleTable::Column.new("TC") { |col|			
				col.width = 40
				col.justification = :right
			}
			tabla.columns["EQUIV"] = PDF::SimpleTable::Column.new("EQUIV") { |col|			
				col.width = 50
				col.justification = :right
			}
			tabla.data = resumen_comprobantes
		end
		tabla.render_on(pdf)		
		pdf.text	"-"*170	
		#Totales
		if tipo == 'confidencial'
			pdf.text "Total Soles : S/. #{detalle_confidencial.select{|os| os.M == 'S/.'}.inject(0) { |t, os| t+=os.TOTAL.to_f}}"
			pdf.text "Total Dolares : US$ #{detalle_confidencial.select{|os| os.M == 'US$'}.inject(0) { |t, os| t+=os.TOTAL.to_f}}"
		elsif tipo == 'resumen_os'
			pdf.text "Total Soles : S/. #{resumen_ordenes_servicio.inject(0) { |t, os| t+=os.SOLES.to_f }}"
			pdf.text "Total Dolares : US$ #{resumen_ordenes_servicio.inject(0) { |t, os| t+=os.DOLARES.to_f}}"
		elsif tipo == 'liquidacion'
			pdf.text "Total Soles : S/. #{resumen_comprobantes.inject(0) { |t, os| t+=os.SOLES.to_f }}"
			pdf.text "Total Dolares : US$ #{resumen_comprobantes.inject(0) { |t, os| t+=os.DOLARES.to_f}}"
			pdf.text "Total Equivalente en Dolares : US$ #{resumen_comprobantes.inject(0) { |t, os| t+=os.EQUIV.to_f}}"
		end
	end
	
	def render_firmas(pdf)
		y = 20
		w = 100
		
		pdf.add_text_wrap(pdf.left_margin+100, y+10, w, "------------------")
		pdf.add_text_wrap(pdf.left_margin+100, y, w, "Responsable")		
		
		pdf.add_text_wrap(pdf.absolute_x_middle+100, y+10, w, "---------------------")
		pdf.add_text_wrap(pdf.absolute_x_middle+100, y, w, "V.B. Proveedor")		
	end
	
	def render_cuentas_y_contactos(pdf)
		fh = 8
		w = 200
		x = pdf.absolute_right_margin - w
		y = pdf.absolute_top_margin
				
		pdf.add_text_wrap(x, y, w, "NRO CUENTAS", fh, :right)
		pdf.add_text_wrap(x, y - 10, w, proveedor.cuentas_by_moneda(moneda).join(' - '), fh, :right)
		
		pdf.add_text_wrap(x, y - 20, w, "CONTACTOS", fh, :right)
		pdf.add_text_wrap(x, y - 30, w, proveedor.contactos.join(' - '), fh, :right)	
	end	
	
	def generar_reserva(_reservas, proveedor_id)
		r = Reserva.new(:proveedor_id => proveedor_id )
		r.seguimientos_reserva << SeguimientoReserva.new(:fecha=>Date.today, :estado_reserva_id => 1)
		r.seguimientos_caja << SeguimientoCaja.new(:fecha=>Date.today, :estado_caja_id => 1)		
		_reservas << r
		r
	end
	
	def obtener_reserva_de(_reservas, reserva_sp)
		rpta = _reservas.select{|r| 
			r.proveedor_id == reserva_sp.servicio.proveedor_id 			
		}
		rpta.size > 0 ? rpta.first : nil			
	end
end

